/*自定义的通用数组类*/
#pragma once
#include <iostream>
using namespace std;

template<class T>
class MyArray {
public:
    //有参构造，参数为数组容量
    MyArray(int capacity) {
        cout << "MyArray有参构造调用" << endl;
        this->m_Capacity = capacity;
        this->m_Size = 0;
        this->pAddress = new T[this->m_Capacity];
    }

    //析构函数
    ~MyArray() {
        cout << "析构函数调用" << endl;
        if (this->pAddress != NULL) {
            delete[] this->pAddress;
            this->pAddress = nullptr;
        }
    }

    //拷贝构造
    MyArray(const MyArray &array) {
        cout << "拷贝构造调用" << endl;
        this->m_Capacity = array.m_Capacity;
        this->m_Size = array.m_Size;
        //深拷贝
        this->pAddress = new T[array.m_Capacity];
        for (int i = 0; i < this->m_Size; ++i) {
            this->pAddress[i] = array.pAddress[i];
        }
    }

    //operator= 防止浅拷贝问题
    MyArray &operator=(const MyArray &array) {
        cout << "operator=调用" << endl;
        //先判断原来堆区是否有数据，如果有先释放
        if (this->pAddress != NULL) {
            delete[] this->pAddress;
            this->pAddress = nullptr;
            this->m_Capacity = 0;
            this->m_Size = 0;
        }
        //深拷贝
        this->m_Capacity = array.m_Capacity;
        this->m_Size = array.m_Size;
        this->pAddress = new T[array.m_Capacity];
        for (int i = 0; i < this->m_Size; ++i) {
            this->pAddress[i] = array.pAddress[i];
        }
        return *this;
    }

    //尾插法
    void Push_Back(const T &val) {
        if (this->m_Capacity == this->m_Size) {
            cout << "数组已满，无法插入" << endl;
            return;
        }
        this->pAddress[this->m_Size] = val;
        this->m_Size++;
    }

    //尾删法
    void Pop_Back() {
        if (this->m_Size == 0) {
            cout << "数组为空，无法删除" << endl;
            return;
        }
        this->m_Size--;
    }

    //通过下标访问
    T &operator[](int index) {
        return this->pAddress[index];
    }

    int getCapacity() const {
        return m_Capacity;
    }

    int getSize() const {
        return m_Size;
    }

    //打印数组
    void printArray() {
        for (int i = 0; i < this->m_Size; ++i) {
            cout << this->pAddress[i] << " ";
        }
        cout << endl;
    }

    //头插法
    void Push_Front(const T &val) {
        if (this->m_Capacity == this->m_Size) {
            cout << "数组已满，无法插入" << endl;
            return;
        }
        for (int i = this->m_Size; i > 0; --i) {
            this->pAddress[i] = this->pAddress[i - 1];
        }
        this->pAddress[0] = val;
        this->m_Size++;
    }

    //头删法
    void Pop_Front() {
        if (this->m_Size == 0) {
            cout << "数组为空，无法删除" << endl;
            return;
        }
        for (int i = 0; i < this->m_Size - 1; ++i) {
            this->pAddress[i] = this->pAddress[i + 1];
        }
        this->m_Size--;
    }

    //根据位置插入
    void Insert(const int &pos, const T &val) {
        if (pos < 0 || pos > this->m_Size) {
            cout << "插入位置不合法" << endl;
            return;
        }
        if (this->m_Capacity == this->m_Size) {
            cout << "数组已满，无法插入" << endl;
            return;
        }
        for (int i = this->m_Size; i > pos; --i) {
            this->pAddress[i] = this->pAddress[i - 1];
        }
        this->pAddress[pos] = val;
        this->m_Size++;
    }

    //根据位置删除
    void Remove(const int &pos) {
        if (pos < 0 || pos >= this->m_Size) {
            cout << "删除位置不合法" << endl;
            return;
        }
        for (int i = pos; i < this->m_Size - 1; ++i) {
            this->pAddress[i] = this->pAddress[i + 1];
        }
        this->m_Size--;
    }

private:
    T *pAddress; //指针指向堆区开辟的真实数组
    int m_Capacity{}; //数组容量
    int m_Size{}; //数组大小
};
